import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
import javax.microedition.rms.*;
import java.util.Date;


public class mobileexpenses extends MIDlet
    implements CommandListener {

  Display display;
  Form mainForm,newExpenseForm,weekExpensesForm,searchExpenseForm;
  DateField dateForNewExpenseField,dateFrom,dateTo;
  TextField amountForNewExpenseField;

  ChoiceGroup typesOfNewExpenseChoice;
  ChoiceGroup typesOfNewExpensePaymentChoice;
  ChoiceGroup typesOfExpenseToSearch;
  ChoiceGroup typesOfPaymentToSearch;

  Alert informationMessage;

  public RecordStore recordStore;

  public static final String MAIN_FORM_TITLE="Spese";
  public static final String NEW_EXPENSE_FORM_TITLE="Registra nuova spesa";

  public static final String NEW_EXPENSE="Nuova spesa";
  public static final String WEEK_EXPENSES="Ultimi sette giorni";

  public static final String SEARCH_EXPENSES="Ricerca spese";
  public static final String CONFIRM_SEARCH="Ricerca";

  public static final String EXIT_COMMAND="Uscita";
  public static final String OK_COMMAND="Ok";
  public static final String CANCEL_COMMAND="Annulla";

  public static final String DATE_LABEL="Data";
  public static final String DATE_LABEL_FROM="Dal giorno";
  public static final String DATE_LABEL_TO="Al giorno";
  public static final String AMOUNT_LABEL="Ammontare";

  public static final String NEW_EXPENSE_REGISTERED="Spesa registrata correttamente";
  public static final String INFORMATION_ALERT_TITLE="Informazioni";

  public static final String TYPE_OF_EXPENSE = "Tipo";
  public static final String[] TYPES_OF_EXPENSE = {"Vitto / Casa",
                                                  "Benzina",
                                                  "Trasporti",
                                                  "Affitto",
                                                  "Medicale",
                                                  "Prelievo",
                                                  "Divertimenti",
                                                  "Sport",
                                                  "Altro",
                                                  "Manutenzione",
                                                  "Bollette",
                                                  "Vestiario"};
  public static final String TYPE_OF_PAYMENT = "Pagamento";
  public static final String[] TYPES_OF_PAYMENT = {"Contanti",
                                                  "Bancomat",
                                                  "Assegno",
                                                  "Carta di Credito",
                                                  "Operazione Bancaria",
                                                  "Altro"};

  public static final int DEFAULT_ALERT_TIMEOUT=2000;

  public void startApp() {
    display = Display.getDisplay(this);

    mainForm = new Form(MAIN_FORM_TITLE);

    dateForNewExpenseField=new DateField(DATE_LABEL,DateField.DATE);
    amountForNewExpenseField=new TextField(AMOUNT_LABEL,"",9,TextField.DECIMAL);

    informationMessage=new Alert(INFORMATION_ALERT_TITLE);
    informationMessage.setTimeout(DEFAULT_ALERT_TIMEOUT);

    newExpenseForm = new Form(NEW_EXPENSE_FORM_TITLE);
    newExpenseForm.append(dateForNewExpenseField);
    newExpenseForm.append(amountForNewExpenseField);

    typesOfNewExpenseChoice=new ChoiceGroup(TYPE_OF_EXPENSE,Choice.POPUP,TYPES_OF_EXPENSE,null);
    typesOfNewExpensePaymentChoice=new ChoiceGroup(TYPE_OF_PAYMENT,Choice.POPUP,TYPES_OF_PAYMENT,null);

    newExpenseForm.append(typesOfNewExpenseChoice);
    newExpenseForm.append(typesOfNewExpensePaymentChoice);

    Command genericOk = new Command(OK_COMMAND, Command.ITEM, 0);
    Command genericCancel = new Command(CANCEL_COMMAND, Command.CANCEL, 0);

    newExpenseForm.addCommand(genericOk);
    newExpenseForm.addCommand(genericCancel);

    weekExpensesForm=new Form(WEEK_EXPENSES);

    searchExpenseForm=new Form(SEARCH_EXPENSES);
    dateFrom=new DateField(DATE_LABEL_FROM,DateField.DATE);
    dateTo=new DateField(DATE_LABEL_TO,DateField.DATE);
    typesOfExpenseToSearch=new ChoiceGroup(TYPE_OF_EXPENSE,Choice.POPUP,TYPES_OF_EXPENSE,null);
    typesOfPaymentToSearch=new ChoiceGroup(TYPE_OF_PAYMENT,Choice.POPUP,TYPES_OF_PAYMENT,null);
    searchExpenseForm.append(dateFrom);
    searchExpenseForm.append(dateTo);
    searchExpenseForm.append(typesOfExpenseToSearch);
    searchExpenseForm.append(typesOfPaymentToSearch);


    Command exitCommand = new Command(EXIT_COMMAND, Command.EXIT, 0);
    Command newExpense = new Command(NEW_EXPENSE, Command.ITEM,0);
    Command weekExpenses = new Command(WEEK_EXPENSES, Command.ITEM,0);
    Command searchExpenses = new Command(SEARCH_EXPENSES,Command.ITEM,0);
    Command confirmSearch = new Command(CONFIRM_SEARCH,Command.ITEM,0);

    searchExpenseForm.addCommand(confirmSearch);

    mainForm.addCommand(exitCommand);
    mainForm.addCommand(newExpense);
    mainForm.addCommand(weekExpenses);
    mainForm.addCommand(searchExpenses);

    mainForm.setCommandListener(this);
    newExpenseForm.setCommandListener(this);
    weekExpensesForm.setCommandListener(this);

    display.setCurrent(mainForm);

    try {
        recordStore=RecordStore.openRecordStore("spese",true);
    } catch (RecordStoreException rse) {
        rse.printStackTrace();
    }

  }

  public void pauseApp () {}

  public void destroyApp(boolean unconditional) {}

  public void commandAction(Command c, Displayable s) {
    System.out.println("Ho schiacciato il bottone "+c.getLabel()+" nello schermo "+s.getTitle());

    if (c.getLabel() == EXIT_COMMAND) {
      try {
          recordStore.closeRecordStore();
      } catch (RecordStoreNotOpenException rsnoe) {
          rsnoe.printStackTrace();
      } catch (RecordStoreException rse) {
          rse.printStackTrace();
      }
      notifyDestroyed();
    }

    if (c.getLabel().equals(OK_COMMAND)) {
       if (s.equals(newExpenseForm)) {
          String newExpenseRecord = dateForNewExpenseField.getDate().getTime()+";"+
                                    amountForNewExpenseField.getString()+";"+
                                    typesOfNewExpenseChoice.getString(typesOfNewExpenseChoice.getSelectedIndex())+";"+
                                    typesOfNewExpensePaymentChoice.getString(typesOfNewExpensePaymentChoice.getSelectedIndex())+";";

          try {
              recordStore.addRecord(newExpenseRecord.getBytes(),0,newExpenseRecord.length());
          } catch (RecordStoreNotOpenException rsnoe) {
              rsnoe.printStackTrace();
          } catch (RecordStoreException rse) {
              rse.printStackTrace();
          }

          informationMessage.setString(NEW_EXPENSE_REGISTERED);

          display.setCurrent(informationMessage);
       }
    }

    if (c.getLabel().equals(CANCEL_COMMAND)) {
       if (s.equals(newExpenseForm)) {
          display.setCurrent(mainForm);
       }
    }

    if (c.getLabel().equals(NEW_EXPENSE)) {
       dateForNewExpenseField.setDate(new Date());
       display.setCurrent(newExpenseForm);
    }

    if (c.getLabel().equals(SEARCH_EXPENSES)) {
      display.setCurrent(searchExpenseForm);
    }

   /* if (c.getLabel().equals(CONFIRM_SEARCH)) {
      try {
          RecordEnumeration recordEnumeration = recordStore.enumerateRecords(,null,false);
          while (recordEnumeration.hasNextElement()) {
      }
    }*/



    if (c.getLabel().equals(WEEK_EXPENSES)) {
       long milliSecondsPerDay=60*60*24*1000;
       Date today=new Date();
       try {
           RecordEnumeration recordEnumeration = recordStore.enumerateRecords(null,null,false);
           while (recordEnumeration.hasNextElement()) {
             Expense expense=new Expense(recordEnumeration.nextRecord());

             if (expense.dateOfExpense.getTime()>today.getTime()-7*milliSecondsPerDay) {

               DateField dateField=new DateField("",DateField.DATE);
               dateField.setDate(expense.dateOfExpense);
               TextField amountField= new TextField("",String.valueOf(expense.amount),3,TextField.DECIMAL & TextField.UNEDITABLE);
               TextField typeField= new TextField("",expense.typeOfExpense,15,TextField.UNEDITABLE);
               TextField paymentField= new TextField("",expense.typeOfPayment,20,TextField.UNEDITABLE);

               weekExpensesForm.append(dateField);
               weekExpensesForm.append(amountField);
               weekExpensesForm.append(typeField);
               weekExpensesForm.append(paymentField);

               dateField.setLayout(Item.LAYOUT_SHRINK);
               paymentField.setLayout(Item.LAYOUT_SHRINK);
               amountField.setLayout(Item.LAYOUT_SHRINK);
               amountField.setLayout(Item.LAYOUT_SHRINK);
             }


           }
           display.setCurrent(weekExpensesForm);
       } catch (RecordStoreNotOpenException rsnoe) {
         rsnoe.printStackTrace();
       } catch (InvalidRecordIDException iride) {
         iride.printStackTrace();
       } catch (RecordStoreException rse) {
         rse.printStackTrace();
       }
    }
  }
}

class Expense {

  public final static int DATE_OF_EXPENSE=0;
  public final static int AMOUNT=1;
  public final static int TYPE_OF_EXPENSE=2;
  public final static int TYPE_OF_PAYMENT=3;


  Date dateOfExpense;
  double amount;
  String typeOfExpense;
  String typeOfPayment;

  Expense(byte[] recordData) {
    String recordString=new String(recordData);
    int start=0;
    int end=0;
    for (int i=0;i<4;i++) {
        end=recordString.indexOf(';',start);
        switch(i) {
           case DATE_OF_EXPENSE:
                this.dateOfExpense=new Date(Long.parseLong(recordString.substring(start,end)));
                break;
           case AMOUNT:
                this.amount=Double.parseDouble(recordString.substring(start,end));
                break;
           case TYPE_OF_EXPENSE:
                this.typeOfExpense=recordString.substring(start,end);
                break;
           case TYPE_OF_PAYMENT:
                this.typeOfPayment=recordString.substring(start,end);
                break;
        }
        start=end+1;
    }
  }
}

class CriterionRecordFilter implements RecordFilter {
  private int fieldId;
  private String fieldValue;

  public CriterionRecordFilter(int fieldId,String fieldValue) {
    this.fieldId=fieldId;
    this.fieldValue=fieldValue;
  }

  public boolean matches(byte[] candidate) {
    Expense tmp=new Expense(candidate);
    boolean ans=false;
    switch(this.fieldId) {
      case Expense.TYPE_OF_EXPENSE:
           if (fieldValue==tmp.typeOfExpense) {
             ans=true;
           } else {
             ans=false;
           }
           break;
      case Expense.TYPE_OF_PAYMENT:
           if (fieldValue==tmp.typeOfPayment) {
             ans=true;
           } else {
             ans=false;
           }
           break;
    }
    return ans;
  }
}